#TODO:
#add published to submission
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _

statusCodes = \
	(
		(0,_('Accepted')),
		(1,_('Compilation error')),
		(2,_('Bad Answer')),
		(3,_('Time limit exceed')),
		(4,_('Memory fault')),
		(5,_('Bad exit code')),
		(6,_('Runtime error')),
		(7,_('Rule violation')),
		(9,_('Service error')),
		(10,_('Not tested')),
	)

goalScoringWays = \
	(
		(0,_('Polish Olimpics way')),
		(1,_('ACM')),
	)

class Compiler(models.Model):
	extension = models.CharField(maxlength=4)
	name = models.CharField(maxlength=64)
	command = models.CharField(_("command to compile, with \%{CODE}s as path to source and \%{OUT}s as path to binary"),maxlength=128)
	def __str__(self):
		return "Compiler %s"%self.name
	class Admin:
		pass

class Problem(models.Model):
	pass
	def get_description(self,lang):
		return self.problemdescription_set.get(lang=lang[:2])
	def __str__(self):
		return "Problem %d"%self.id
	class Admin:
		pass

class ProblemDescription(models.Model):
	problem = models.ForeignKey(Problem)
	lang = models.CharField(maxlength=3)
	description = models.TextField(_("problem description"))
	input = models.TextField(_("specification of problem input"))
	output = models.TextField(_("specification of problem output"))
	testExamples = models.TextField(_("test examples for problem"))
	class Admin:
		pass

class Test(models.Model):
	problem = models.ForeignKey(Problem)
	name = models.SlugField(_("part of file name before .in and .out"),maxlength=16)
	checkTime = models.DateTimeField(_("date time, when test should be checked"))
	maxTime = models.IntegerField(_("maximal run time in MILISECONDS"))
	memLimit = models.IntegerField(_("memory limit for test - in kilobytes"))
	class Admin:
		pass

class Task(models.Model):
	problem = models.ForeignKey(Problem)
	slug = models.SlugField(_("short name of task"),maxlength=32,unique=True)
	startTime = models.DateTimeField(_("when start showing task"))
	endTime = models.DateTimeField(_("end of solutions submiting time"))
	maxPoints = models.IntegerField(_("maximal score for task, filled automatically"),blank=True,default=0)
	def get_name(self,lang):
		try:
			return self.taskname_set.get(lang=lang[:2]).name
		except TaskName.DoesNotExist:
			raise self.DoesNotExist
	class Admin:
		pass

class TaskName(models.Model):
	task = models.ForeignKey(Task)
	lang = models.CharField(maxlength=3)
	name = models.CharField(_("task name"),maxlength=64)
	class Admin:
		pass

class Goal(models.Model):
	task = models.ForeignKey(Task)
	tests = models.ManyToManyField(Test)
	maxPoints = models.IntegerField(_("maximal score for goal"))
	resultsTime = models.DateTimeField(_("when results should be shown"))
	published = models.BooleanField(_("if it has been checked and included in results"),default=False,blank=True)
	scoringWay = models.IntegerField(_("scoring type for goal"),choices=goalScoringWays)
	secret = models.BooleanField(_("if user cannot view results of its tests"),default=False)
	def __str__(self):
		return "Goal %d"%self.id
	class Admin:
		pass

class Contest(models.Model):
	tasks = models.ManyToManyField(Task)
	slug = models.SlugField(_("short name of contest"),maxlength=32,unique=True)
	maxPoints = models.IntegerField(_("maximal score for contest, filled automatically"),blank=True,default=0)
	startTime = models.DateTimeField(_("when start showing contest"))
	def get_name(self,lang):
		try:
			return self.contestname_set.get(lang=lang[:2]).name
		except ContestName.DoesNotExist:
			raise self.DoesNotExist
	class Admin:
		pass

class ContestName(models.Model):
	contest = models.ForeignKey(Contest)
	lang = models.CharField(_("language code"),maxlength=3)
	name = models.CharField(_("task name"),maxlength=64)
	class Admin:
		pass

class Submission(models.Model):
	user = models.ForeignKey(User)
	task = models.ForeignKey(Task)
	comp = models.ForeignKey(Compiler)
	code = models.TextField(_("source code of submission"))
	insertTime = models.DateTimeField(_("time of submission insertion"),auto_now_add=True)
	points = models.IntegerField(_("points for submission"),blank=True,default=0)
	#checked = models.BooleanField(_("if it has been checked and included in results"),default=False,blank=True)
	status = models.IntegerField(_("status"),choices=statusCodes,default=10,blank=True)
	compiled = models.BooleanField(_("true if compilation succeeded, false if failed,NULL if not compiled"),null=True,blank=True)
	compilationOutput = models.TextField(_("Output from compiler"),default="",blank=True)
	class Admin:
		pass

class GoalResults(models.Model):
	submission = models.ForeignKey(Submission)
	goal = models.ForeignKey(Goal)
	points = models.IntegerField(_("points for goal"),default=0)
	#checked = models.BooleanField(_("if it has been checked and included in results"),default=False,blank=True)
	status = models.IntegerField(_("status"),choices=statusCodes,default=10)
	firstFail = models.IntegerField(_("first test, where failed"),default=0)
	class Admin:
		pass

class TestResults(models.Model):
	test = models.ForeignKey(Test)
	submission = models.ForeignKey(Submission)
	time = models.IntegerField(_("running time"),default=0)
	status = models.IntegerField(_("status"),choices=statusCodes,default=10)
	comment = models.CharField(maxlength = 64)
	class Admin:
		pass


class TaskResults(models.Model):
	user = models.ForeignKey(User)
	task = models.ForeignKey(Task)
	lastPoints = models.IntegerField(_("points received for last solution"),default=0)
	bestPoints = models.IntegerField(_("points received for best solution"),default=0)
	submissions = models.IntegerField(_("how many submissions has user submited"),default=0,blank=True)
	class Admin:
		pass

class ContestResults(models.Model):
	user = models.ForeignKey(User)
	contest = models.ForeignKey(Contest)
	lastPoints = models.IntegerField(_("sum of points received for last solutions of each task"),default=0)
	bestPoints = models.IntegerField(_("sum of points received for best solutions of each task"),default=0)
	class Admin:
		pass
